import { HttpException, Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from './entities/user.entity';
import { Repository } from 'typeorm';
import { PaginationService } from '../../common/pagination/pagination.service';
import { encryptText, verifyText } from '../../utils/bcryptjs';
import { ChangePasswordDto } from './dto/change-password.dto';

@Injectable()
export class UserService {
  /** user 实体注册 */
  constructor(
    @InjectRepository(User) private readonly userRepository: Repository<User>,
    private pageService: PaginationService<User>,
  ) {
    this.pageService = new PaginationService<User>(this.userRepository);
  }

  // 创建用户
  async create(createUserDto: CreateUserDto): Promise<User> {
    const user = await this.findOenByUsername(createUserDto.username);
    if (user && user.username === createUserDto.username) {
      throw new HttpException('用户已存在!', 401);
    }
    createUserDto.password = encryptText(createUserDto.password, 10);
    return await this.userRepository.save(createUserDto);
  }

  // 分页查询用户列表
  async findAll(params: { page: number; pageSize: number }) {
    const res = await this.pageService.paginate({
      ...params,
      options: {
        select: [
          'id',
          'username',
          'nickname',
          'gender',
          'avatar',
          'email',
          'phone',
          'remark',
        ],
        where: { status: 1, isDeleted: 0 },
        relations: { roles: true },
      },
    });
    return res;
  }

  // 分页查询接口
  pageSearch(params: {
    page: number;
    pageSize: number;
    username: string;
    nickname: string;
    phone: string;
    gender: string;
  }) {
    const { page, pageSize, username, nickname, phone, gender } = params;
    // 定义查询构造器
    const qb = this.userRepository.createQueryBuilder('user');
    // 查询部分字段
    qb.select([
      'user.id',
      'user.username',
      'user.nickname',
      'user.gender',
      'user.avatar',
      'user.email',
      'user.phone',
      'user.remark',
    ]);
    // 模糊查询username、nickname、phone字段
    if (username) {
      qb.andWhere('user.username like :username', {
        username: `%${username}%`,
      });
    }
    if (nickname) {
      qb.andWhere('user.nickname like :nickname', {
        nickname: `%${nickname}%`,
      });
    }
    if (phone) {
        qb.andWhere('user.phone like :phone', {
          phone: `%${phone}%`,
        });
    }
    gender && qb.andWhere('user.gender = :gender', { gender: gender });

    // console.log('pageSearch params', params);
    // 分页查询
    return this.pageService.pageSearch({
      page,
      pageSize,
      queryBuilder: qb,
    });
  }

  // 获取用户信息
  async findOne(id: string): Promise<User> {
    const user = await this.userRepository.findOne({
      select: [
        'id',
        'nickname',
        'username',
        'gender',
        'avatar',
        'email',
        'phone',
        'remark',
      ],
      where: { status: 1, isDeleted: 0, id },
      relations: { roles: true },
    });
    if (!user) throw new HttpException('用户不存在', 400);
    return user;
  }

  async findOenByUsername(username: string): Promise<User> {
    return await this.userRepository.findOneBy({ username });
  }
  // 更新用户信息
  async update(id: string, updateUserDto: UpdateUserDto) {
    const user = await this.findOne(id);
    if (!user) throw new HttpException('用户不存在', 401);
    const updateUser = this.userRepository.merge(user, updateUserDto);
    return await this.userRepository.save(updateUser);
  }

  // 管理员修改密码接口 changePassword
  async modifyPassword(id: string, dto: ChangePasswordDto) {
    if (dto.password !== dto.checkPassword) {
      throw new HttpException('两次输入的密码不一致，请修改一致后重试', 500);
    }
    const user = await this.findOne(id);
    if (!user) throw new HttpException('用户不存在', 401);
    if (dto.password) {
      dto.password = encryptText(dto.password, 10);
    }
    const updateUser = this.userRepository.merge(user, dto);
    return await this.userRepository.save(updateUser);
  }

  // 用户修改密码接口
  async updateUserPwd(id: string, dto: ChangePasswordDto) {
    if (dto.password !== dto.checkPassword) {
      throw new HttpException('两次输入的密码不一致，请修改一致后重试', 500);
    }
    const user = await this.findOne(id);
    if (!user) throw new HttpException('用户不存在', 401);
    // 密码对比
    const compare: boolean = verifyText(dto.oldPassword, user.password);
    console.log('原密码密码对比:==>', compare);
    // 密码不正确
    if (!compare) throw new HttpException('原密码不正确！', 500);
    if (dto.password) {
      dto.password = encryptText(dto.password, 10);
    }
    const updateUser = this.userRepository.merge(user, dto);
    return await this.userRepository.save(updateUser);
  }

  // 删除用户-软删
  async remove(id: string): Promise<any> {
    const user = await this.findOne(id);
    if (!user) throw new HttpException('用户不存在', 401);
    return await this.userRepository.update(id, { isDeleted: 1 });
  }
}
